import Axios from "axios";
import {CACHE_EXPIRE_TIME, ENABLE_HTTP_CACHE, NET_CACHE_LOG} from "~/Contants";
import * as _ from "lodash";

let cachePool = {};
let cachingPool = {};

const CACHED_MARK = "_cached_mark";

function log(...args) {
    if(NET_CACHE_LOG===true){
        console.log(...args);
    }
}

/**
 * 清空缓存
 */
export function cleanCache(){
    cachePool = {};
}

/**
 * 发起缓存get
 */
export async function cachedGet(url,config){
    if(config.cache===undefined) _.assign(config,{cache:true});
    const key = `${url}?${JSON.stringify(config.params)}`;
    const cachingMeta = cachingPool[key];
    if(cachingMeta){
        log(`阻塞get请求:${key}`);
        return cachingMeta.promise;
    }else {
        log(`发起不重叠get:${key}`);
        const responsePromise = Axios.get(url,config);
        cachingPool[encodeConfig(`${url}?${JSON.stringify(config.params)}`)] = {promise:responsePromise};
        const response = await responsePromise;
        delete cachingPool[encodeConfig(`${url}?${JSON.stringify(config.params)}`)];
        return response;
    }
}

function encodeConfig(config){
    return `${config.url}?${JSON.stringify(config.params)}`;
}

Axios.interceptors.request.use(config=>{
    if(ENABLE_HTTP_CACHE&&config.hasOwnProperty("cache")&&config["cache"]===true){
        const key = encodeConfig(config);
        let cacheMeta = cachePool[key];
        if(cacheMeta){
            let timeLimit = cacheMeta["timeLimit"]?cacheMeta["timeLimit"]:CACHE_EXPIRE_TIME;
            if (Date.now() - cacheMeta.cacheTime <= timeLimit) {
                let source = Axios.CancelToken.source();
                config.cancelToken = source.token;
                config[CACHED_MARK] = true;
                log(`使用被缓存的请求[${key}]`,cacheMeta);
                source.cancel(cacheMeta);
            } else {
                console.log(`缓存[${key}]已过期。`);
                delete cachePool[key];
            }
        }
    }
    return config;
});

Axios.interceptors.response.use(
    response=>{
        if(response.config["cache"] === true){
            let cacheMeta = {data:response,cacheTime:Date.now()};
            if(typeof response.config["cacheTime"]==="number")cacheMeta.timeLimit = response.config["cacheTime"];
            cachePool[encodeConfig(response.config)] = cacheMeta;
            log(`缓存请求:${encodeConfig(response.config)}:`,cacheMeta);
        }
        return response;
    },
    error => {
        if(Axios.isCancel(error)) return Promise.resolve(error.message.data);
        else return Promise.reject(error);
    }
);